
<script setup lang="ts">
import { ref, onMounted, reactive } from "vue";
import { message } from "ant-design-vue";
import type { CascaderProps } from "ant-design-vue";
import { translateTree, randomColor } from "@/utils/utils";
import {
  CustomerServiceOutlined,
  CommentOutlined,
  UploadOutlined,
  PlusOutlined,
  LoadingOutlined,
  EyeOutlined,
  DeleteOutlined,
} from "@ant-design/icons-vue";
import type { UploadChangeParam, UploadProps } from "ant-design-vue";
import { getTagCate, pushArticle } from "@/api/article";
import {addTag} from '@/api/tag'
import { upload } from "@/api/upload";
import { useStore } from "vuex";
import { objectType } from "ant-design-vue/es/_util/type";
const store = useStore();

// 封面图片上传的地址和配置
let action = process.env.VUE_APP_BASE + "api/upload/img";
let headers = { authorization: store.state.user.token };
let coverImgUrl = ref<string>("");
let isUploadCoverLoading = ref<boolean>(false);
let fileList = ref([]);
// 分类和标签的配置

let cateOption: CascaderProps["options"] = [];

let cateConfig = reactive<{
  cates: Array<any>;
  tags: Array<any>;
}>({
  cates: [],
  tags: [],
});

// 获取分类 标签配置信息
let getConfig = async () => {
  let res: any = await getTagCate();
  if (res.code == 200) {
    cateConfig.cates = translateTree(res.cates, 0);
    cateOption = cateConfig.cates;
    cateConfig.tags = res.tags;
  } else {
    message.error("获取配置信息失败");
  }
};

// 当分类改变处理函数
let cascaderChangeHandler = (value: any, selectedOptions: any) => {
  publicFormState.cates = value;
};

/*添加标签处理函数*/
let tagsChangeHandler = (tagItem: any) => {
  let result = publicFormState.tags.find(
    (item: any) => item.tagId == tagItem.tagId
  );
  if (result) {
    tagItem["checked"] = false;
    closeTagHandler(tagItem);
    return;
  }
  tagItem["checked"] = true;
  publicFormState.tags.push(tagItem);
};

// 关闭已经有的标签 处理函数
let closeTagHandler = (tagItem: any) => {
  tagItem["checked"] = false;
  let index = publicFormState.tags.findIndex(
    (item: any) => item.tagId == tagItem.tagId
  );
  publicFormState.tags.splice(index, 1);
};

// 上传封面前检查图片的类型
// @ts-ignore
let beforeUploadCover = (file: UploadProps["fileList"][number]) => {
  var imgfileType = [
    "image/gif",
    "image/jpeg",
    "image/jpg",
    "image/pjpeg",
    "image/x-png",
    "image/png",
  ];
  const isJpgOrPng = imgfileType.includes(file.type);
  if (!isJpgOrPng) {
    message.error("图片格式有误,支持上传jpg,png,gif");
    return;
  }
  return true;
};

// 状态改变
let handleUploadChange = (info: UploadChangeParam) => {
  if (info.file.status === "uploading") {
    isUploadCoverLoading.value = true;
    return;
  }
  if (info.file.status === "done") {
    isUploadCoverLoading.value = false;
    coverImgUrl.value =  info.file.response.data.url;
    publicFormState.articleCover = info.file.response.data.url;
    message.success("封面图片上传成功");
  }
  if (info.file.status === "error") {
    isUploadCoverLoading.value = false;
    message.error("upload fail");
    return;
  }
};
// 封面预览
// @ts-ignore
let handlePreviewCover = (file: UploadProps["fileList"][number]) => {
  previewConfig.visable = true;
  previewConfig.previewImagePath = coverImgUrl.value;
  previewConfig.previewTitle = "封面预览";
};

/**
 * @description 全部图片预览
 * */

let previewVisible = ref<boolean>(false); // 控制是否显示
let previewConfig = reactive<{
  visable: boolean;
  previewTitle: string;
  previewImagePath: string;
  handleCancel: () => void;
}>({
  visable: false,
  previewTitle: "图片预览",
  previewImagePath: "",
  handleCancel: () => {
    previewConfig.visable = false;
  },
});

onMounted(() => {
  getConfig();
});

// 需要上传的表单数据
let publicFormState = reactive<{
  articleTitle: string;
  articleContent: string;
  cates: Array<any>;
  tags: Array<any>;
  articleCover: string;
  articleDesc:string
  isLock?:Boolean
  pwd?:string
}>({
  articleTitle: "",
  articleContent: "",
  cates: [],
  tags: [],
  articleCover: "",
  articleDesc:"",
  isLock:false,
  pwd:""
});

let handleUploadImage = async (event: any, isertImage: any, files: any) => {
  try {
    let formData = new FormData();
    formData.append("file", files[0]);
    let res: any = await upload(formData);
    // console.log(res);
    if (res.code !== 200) return message.error(res.message);
    //   橙红处理函数
    isertImage({
      url: (process.env.VUE_APP_BASE + res.data.url).replace(/\\/g, "/"),
      desc: res.data.originalname,
      width: "50%",
      height: "auto",
    });
    message.success("图片插入成功!");
  } catch (e: any) {
    message.error(e.message);
  }
};

// 读取本地缓存
let readLocalText = () => {
  let key = 1;
  if (store.state.article.saveText !== "") {
    message.loading({ content: "正在读取本地缓存", key });
    publicFormState.articleTitle = store.state.article.title;
    publicFormState.articleContent = store.state.article.saveText;
    message.success({ content: "read success", key });
  }
};
readLocalText();

// 保存处理函数
let saveHandler = (text: string, html: string) => {
  if (
    publicFormState.articleTitle !== "" &&
    publicFormState.articleContent !== ""
  ) {
    store.commit("article/SET_SAVETEXT", text);
    store.commit("article/SET_ARTICLE_TITLE", publicFormState.articleTitle);
    message.success("本地保存成功");
  } else {
    message.error("标题内容不能为空");
  }
};
// 发表文章按钮 添加封面
let publicArticle = () => {
  openModal.value = true;
};

// 发布文章弹窗
let openModal = ref<boolean>(false);
let publicArticleIsLoading = ref<boolean>(false);
// 取消发布文章弹窗
function publicArticleHandleCancel() {
  openModal.value = false;
  resetPublicModalFormState();
}

// 取文章标题填充到当前文章摘要
function TakeArticleTitle(){
  publicFormState.articleTitle == '' ? message.warn('标题为空,请手动输入') : publicFormState.articleDesc = publicFormState.articleTitle
}

// 重置提交表单到初始状态
let resetPublicModalFormState = () => {
  publicFormState.tags = [];
  publicFormState.cates = [];
  publicFormState.articleCover = "";
  publicFormState.articleDesc = ""
  cateConfig.cates = [];
  fileList.value = []
  publicFormState.isLock = false;
  publicFormState.pwd = "";
  cateConfig.tags.forEach((item: any) => {
    if (item.checked) {
      item.checked = false;
    }
  });
};

function clearMd() {
  publicFormState.tags = [];
  publicFormState.cates = [];
  publicFormState.articleCover = "";
  publicFormState.articleTitle = "";
  publicFormState.articleContent = "";
  publicFormState.articleDesc = ""
  publicFormState.isLock = false;
  publicFormState.pwd = "";
  store.commit("article/SET_SAVETEXT", "");
  store.commit("article/SET_ARTICLE_TITLE", "");
}

// 清理整页面数据
let clearPageSource = () => {
  resetPublicModalFormState();
  clearMd();
};
// 确认发布按钮
async function publicArticleOkHandler() {
  if (
    publicFormState.articleContent.trim() == "" ||
    publicFormState.articleContent == ""
  )
    return message.error("文章标题和内容不能为空");
    if(publicFormState.articleDesc == '')
    return message.error('文章摘要不能为空')
  if (publicFormState.tags.length == 0) return message.error("请选择文章标签");
  if (publicFormState.cates.length == 0)
    return message.error("请选择文章所属分类");
  try {
    publicArticleIsLoading.value = true;
    let articleTags: Array<string | number> = [];
    publicFormState.tags.forEach((item: any) => {
      articleTags.push(item.tagId);
    });
    let cates: string = publicFormState.cates.join(",");
    let tags: string = articleTags.join(",");
    let form = {
      articleTitle: publicFormState.articleTitle,
      articleContent: publicFormState.articleContent,
      articleCover: publicFormState.articleCover,
      cates,
      tags,
      articleDesc:publicFormState.articleDesc,
      isLock:publicFormState.isLock ? 1 : 0,
      articlePassword:publicFormState.isLock ?  publicFormState.pwd == "" ? "200110" : "" : ""
    };
    let res: any = await pushArticle(form);
    publicArticleIsLoading.value = false;
    console.log(res);
    if (res.code == 200) {
      message.success("文章发布成功");
      openModal.value = false;
      clearPageSource();
    }
  } catch (err: any) {
    publicArticleIsLoading.value = false;
    message.error(err.message);
  }
}

// 预览
let AimageConfig = reactive({
  PrievewPath:'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
  visible:false,
  setVisible:(visable:any,prev:any) => {
    AimageConfig.visible = visable
  }
})


/*图片点击处理函数*/
let imgClickHandler = (images: Array<string>, currentIndex: number) => {
  console.log(images, currentIndex);
  AimageConfig.PrievewPath = images[currentIndex]
  AimageConfig.visible = true
};

let addTagName = ref<string>('')
let addTagShow = ref<boolean>(false)
// 添加标签
let addTagClick = () => {
  addTagShow.value = true
}
// 添加tag成功处理函数
let addTagOkHandler = async () => {
  let tagName = addTagName.value
  if (!tagName) {
    return message.error('标签名不能为空')
  }
  let addTagform = { tagName,tagDesc:tagName,tagAlias:tagName };
  let data:any = await addTag(addTagform)
  addTagShow.value = false
  console.log('添加成功',data);
  if(data.code == 200) {
    message.success('添加成功')
    getConfig()
  }else {
    message.error('添加失败')
  }
}
// 取消添加tag
let cancelTagOkHandler = () => {
  addTagName.value = ''
  addTagShow.value = false
}


</script>


<template>
  <div class="creation-container">
    <!--  添加发布文章标题-->
    <a-row class="article-title-utils-box">
      <div class="left-input">
        <a-input
          v-model:value="publicFormState.articleTitle"
          placeholder="请输入文章标题(5-100)个字"
        ></a-input>
      </div>
      <div class="utils">
        <button @click="publicArticle" class="public-article-btn">
          <UploadOutlined />发表文章
        </button>
      </div>
    </a-row>
    <v-md-editor
      codemirror-style-reset
      v-model="publicFormState.articleContent"
      height="calc(100vh - 210px)"
      :disabled-menus="[]"
      @save="saveHandler"
      left-toolbar="undo redo | bold italic strikethrough | table quote code line-numbers | ul ol task check list-ul list-ol | link image emoji todo-list | save "
      @image-click="imgClickHandler"
      @upload-image="handleUploadImage"
    ></v-md-editor>
    <a-float-button-group
      trigger="hover"
      type="primary"
      :style="{ right: '24px' }"
    >
      <template #icon>
        <UploadOutlined />
      </template>
      <!--    上传-->
      <a-float-button>
        <template #icon>
          <UploadOutlined />
        </template>
      </a-float-button>
    </a-float-button-group>
    <a-modal
      body-style="margin-top:35px"
      v-model:open="openModal"
      title="发表文章"
    >
      <!-- 添加表单 -->
      <a-form :model="publicFormState" name="basic" autocomplete="off">
        <a-form-item label="文章标题" name="username">
          <a-typography-paragraph
            v-model:content="publicFormState.articleTitle"
            editable
          />
        </a-form-item>
        <!-- 文章摘要 -->
        <a-form-item label="文章摘要" name="文章摘要">
          <a-input v-model:value="publicFormState.articleDesc" placeholder="请填写文章的摘要">
          </a-input>
          <a-button style="text-align: right; margin-top: 15px" @click="TakeArticleTitle">取文章标题</a-button>
        </a-form-item>
        <a-form-item label="文章分类" name="文章分类">
          <a-cascader
            @change="cascaderChangeHandler"
            v-model:value="publicFormState.cates"
            :options="cateOption"
            placeholder="Please select"
          />
        </a-form-item>
        <!--  标签  -->
        <a-form-item label="文章标签" name="文章标签">
          <a-space :size="[0, 'small']" wrap>
            <template  v-if="publicFormState.tags.length !== 0">
              <a-tag
              @close="closeTagHandler(item)"
              v-for="item in publicFormState.tags"
              :key="item"
              :bordered="true"
              closable
              :color="randomColor()"
              >{{ item.tagName }}</a-tag
            >
            </template>
            <a-tag v-else :bordered="true">暂无标签</a-tag>
          </a-space>
        </a-form-item>
        <a-form-item label="文章上锁" name="文章上锁">
          <a-switch :checked="publicFormState.isLock" @change="publicFormState.isLock = !publicFormState.isLock" />
        </a-form-item>
        <a-form-item label="文章密码" name="文章密码" v-if="publicFormState.isLock">
          <a-input v-model="publicFormState.pwd" placeholder="文章加密访问的密码"/>
        </a-form-item>
        <!-- 添加新标签 -->
        <a-form-item v-if="addTagShow" label="新标签名" name="添加新标签">
          <a-input v-model:value="addTagName" placeholder="填写新标签名称">
          </a-input>
          <a-button style="text-align: right; margin-top: 15px;margin-right: 15px;" size="small" @click="cancelTagOkHandler">取消</a-button>
          <a-button type="primary" style="text-align: right; margin-top: 15px" size="small" @click="addTagOkHandler">确认</a-button>
        </a-form-item>
        <a-form-item class="choose-tags">
          <h5>点击添加标签</h5>
          <a-space :size="[0, 'small']" wrap>
            <a-tag
              :class="[item.checked ? 'checked-tag-item' : '']"
              v-for="item in cateConfig.tags"
              :bordered="false"
              @click="tagsChangeHandler(item)"
              :key="item.tagId"
              >{{ item.tagName }}</a-tag
            >
            <a-tag @click="addTagClick"><PlusOutlined />添加标签</a-tag>
          </a-space>
        </a-form-item>
        <!--      封面  图片上传-->
        <a-form-item label="上传图片封面">
          <a-upload
            v-model:file-list="fileList"
            max-count="5"
            method="POST"
            :headers="headers"
            name="file"
            list-type="picture-card"
            class="avatar-uploader"
            :show-upload-list="false"
            :action="action"
            :before-upload="beforeUploadCover"
            @change="handleUploadChange"
          >
            <div class="img-view-s" v-if="coverImgUrl">
              <img :src="coverImgUrl" alt="avatar" />
              <div class="icon-util">
                <EyeOutlined @click.stop="handlePreviewCover"></EyeOutlined>
                <DeleteOutlined />
              </div>
            </div>
            <div v-else>
              <loading-outlined v-if="isUploadCoverLoading"></loading-outlined>
              <plus-outlined v-else></plus-outlined>
              <div class="ant-upload-text">Upload</div>
            </div>
          </a-upload>
        </a-form-item>

        <!-- 上传封面图片外链 -->
        <a-form-item label="封面外链">
          <a-input v-model:value="publicFormState.articleCover" placeholder="请输入封面图片外链" />
        </a-form-item>
      </a-form>
      <template #footer>
        <a-button key="back" @click="publicArticleHandleCancel">取消</a-button>
        <a-button
          key="submit"
          type="primary"
          :loading="publicArticleIsLoading"
          @click="publicArticleOkHandler"
          >发布文章</a-button
        >
      </template>
    </a-modal>
    <!-- 封面   全屏图片预览-->
    <a-modal
      :open="previewConfig.visable"
      :title="previewConfig.previewTitle"
      :footer="null"
      @cancel="previewConfig.handleCancel"
    >
      <img
        alt="example"
        style="width: 100%"
        :src="previewConfig.previewImagePath"
      />
    </a-modal>
    <!--  全部预览  -->
    <a-image
        :style="{ display: 'none' }"
        :preview="{
          visible:AimageConfig.visible,
          onVisibleChange: AimageConfig.setVisible,
        }"
        :width="200"
        :src="AimageConfig.PrievewPath"
    />
  </div>
</template>


<style lang="scss" scoped>
.article-title-utils-box {
  padding: 15px 0px;
  .left-input {
    padding: 0px 10px;
    flex: 1;
    .ant-input {
      border-radius: 50px;
      background-color: #fff;
      height: 40px;
      line-height: 100%;
      font-size: 16px;
      text-indent: 12px;
      color: #1f0808;
      &:focus {
        border-color: #d9d9d9;
        box-shadow: none;
      }
      &::-webkit-input-placeholder {
        color: #757373;
        background-color: white;
      }
      &:hover {
        border-color: #d9d9d9;
      }
    }
  }
  //  发表文章
  .utils {
    display: flex;
    align-items: center;
    padding: 0px 20px;
    .public-article-btn {
      outline: none;
      border: none;
      padding: 10px 16px;
      font-size: 16px;
      color: #fff;
      border: none;
      border-radius: 18px;
      white-space: nowrap;
      transition: 0.3s all;
      cursor: pointer;
      background-color: rgba(22, 119, 255, 0.8);

      &:hover {
        background: rgb(22, 119, 255);
      }
    }
  }
}
.ant-modal-header {
  margin-bottom: 24px;
}
.ant-typography {
  margin-bottom: 0px;
}
.choose-tags {
  padding: 14px 10px;
  background-color: rgba(246, 245, 245, 0.71);
  border-radius: 8px;
  max-height: 144.5px;
  overflow-y: auto;
  .ant-tag {
    cursor: pointer;
    padding: 4px 8px;
    background-color: rgba(217, 217, 217, 0.85);
    transition: 0.3s all;
    border: none;
    &:hover {
      color: #fff;
      background-color: #1285f1;
    }
  }
  .checked-tag-item {
    color: #fff;
    background-color: #1285f1;
  }
}
.ant-upload {
  img {
    width: 100%;
    object-fit: cover;
  }
}
.img-view-s {
  position: relative;
  width: 100%;
  &:hover .icon-util {
    display: flex;
  }
}
.icon-util {
  transition: 0.3s all;
  width: 100%;
  height: 100%;
  display: none;
  position: absolute;
  align-items: center;
  justify-content: space-evenly;
  top: 0px;
  left: 0px;
  background-color: rgba(0, 0, 0, 0.5);
  color: #fff;
}
</style>


<style>
.bread-crumder {
  position: sticky;
  top: 0px;
  z-index: 2;
}
</style>
